/*******************************************************************************
 * Descharts library
 * Copyright (c) 2014 Bradipao <bradipao@gmail.com>
 * https://plus.google.com/+SidBradipao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/

package it.bradipao.lib.descharts;

import ohos.agp.utils.Color;

import java.util.ArrayList;

/**
 * ChartValueSerie() class represents a line graph to be plotted.
 * It contains dataset of LABEL,Y couples (ChartValue class) and
 * some graphical properties of line (color and width).
 *
 * @since 2021-08-09
 */
public class ChartValueSerie {
    private boolean mShow = true;
    private boolean mAutoYminmax = true;
    /**
     * mPointList
     */
    public ArrayList<ChartValue> mPointList = new ArrayList<ChartValue>();
    /**
     * mColor
     */
    public int mColor = Color.getIntColor("#FF000000");
    /**
     * mFillColor
     */
    private int mFillColor = Color.getIntColor("#00000000");
    /**
     * mWidth
     */
    public float mWidth = 2;
    /**
     * mUseDip
     */
    public boolean mUseDip = true;
    /**
     * float
     */
    public float mYmin = 0;
    /**
     * float
     */
    public float mYmax = 1;

    /**
     * Constructor, properties are default.
     */
    public ChartValueSerie() {
    }

    /**
     * Constructor, properties are default except color.
     *
     * @param color color
     */
    public ChartValueSerie(int color) {
        mColor = color;
    }

    /**
     * Constructor, properties are default except color and width.
     *
     * @param color color
     * @param width width
     */
    public ChartValueSerie(int color, float width) {
        mColor = color;
        mWidth = width;
    }

    /**
     * Constructor, color, width and usedip are provided.
     *
     * @param color color
     * @param width width
     * @param usedip usedip
     */
    public ChartValueSerie(int color, float width, boolean usedip) {
        mColor = color;
        mWidth = width;
        mUseDip = usedip;
    }

    /**
     * getFillColor
     *
     * @return getFillColor
     */
    public int getFillColor() {
        return mFillColor;
    }

    /**
     * Returns the ArrayList of points dataset.
     *
     * @return ArrayList
     */
    public ArrayList<ChartValue> getPointList() {
        return mPointList;
    }

    /**
     * Sets the ArrayList of points dataset.
     *
     * @param points points
     */
    public void setPointList(ArrayList<ChartValue> points) {
        this.mPointList = points;
    }

    /**
     * Clears the ArrayList of points dataset.
     */
    public void clearPointList() {
        this.mPointList.clear();
    }

    /**
     * Adds a point to the ArrayList of points dataset.
     *
     * @param point point
     */
    public void addPoint(ChartValue point) {
        // update range first
        if (mAutoYminmax) {
            if (mPointList.size() > 0) {
                if (point.y > mYmax) {
                    mYmax = point.y;
                } else if (point.y < mYmin) {
                    mYmin = point.y;
                }
            } else {
                mYmin = mYmax = point.y;
            }
        }
        mPointList.add(point);
    }

    /**
     * Shifts a point to the ArrayList of points dataset.
     * * Adding is done calling addPoint(), then points are removed
     * * from the beginning of the list untile there are maximum
     * * max points in the list.
     *
     * @param point point
     * @param max max
     */
    public void shiftPoint(ChartValue point, int max) {
        addPoint(point);
        while (mPointList.size() > max) {
            mPointList.remove(0);
        }
        if (mAutoYminmax) {
            calcRanges();
        }
    }

    /**
     * Removes a point from the points dataset.
     *
     * @param point point
     */
    public void removePoint(ChartValue point) {
        mPointList.remove(point);
        if (mAutoYminmax) {
            calcRanges();
        }
    }

    /**
     * Returns a point from the points dataset.
     *
     * @param index index
     * @return ChartValue
     */
    public ChartValue getPoint(int index) {
        return mPointList.get(index);
    }

    /**
     * Update a point in the points dataset.
     *
     * @param index index
     * @param y y
     */
    public void updatePoint(int index, float y) {
        mPointList.get(index).y = y;
        if (mAutoYminmax) {
            calcRanges();
        }
    }

    /**
     * Returns size of the points dataset.
     *
     * @return int
     */
    public int getSize() {
        return mPointList.size();
    }

    /**
     * Calculates maximum and minimum of both X and Y coordinates
     * * in the points dataset.
     */
    private void calcRanges() {
        int i;
        if (mPointList.size() == 0) {
            return;
        }
        if (mAutoYminmax) {
            mYmin = mPointList.get(0).y;
            mYmax = mPointList.get(0).y;
            for (i = 1; i < mPointList.size(); i++) {
                if (mPointList.get(i).y > mYmax) {
                    mYmax = mPointList.get(i).y;
                } else if (mPointList.get(i).y < mYmin) {
                    mYmin = mPointList.get(i).y;
                }
            }
        }
    }

    /**
     * Setter for AutoMinMax properties.
     *
     * @param bAutoY bAutoY
     */
    public void setAutoMinmax(boolean bAutoY) {
        this.mAutoYminmax = bAutoY;
        if (bAutoY) {
            calcRanges();
        }
    }

    /**
     * Setter for AutoMinMax properties and values.
     *
     * @param bAutoY bAutoY
     * @param fYmin fYmin
     * @param fYmax fYmax
     */
    public void setAutoMinmax(boolean bAutoY, float fYmin, float fYmax) {
        this.mAutoYminmax = bAutoY;
        if (!bAutoY) {
            this.mYmin = fYmin;
            this.mYmax = fYmax;
        }
        if (bAutoY) {
            calcRanges();
        }
    }

    /**
     * Setter for Show property.
     *
     * @param bShow bShow
     */
    public void setVisible(boolean bShow) {
        this.mShow = bShow;
    }

    /**
     * Returns state of Show property.
     *
     * @return boolean
     */
    public boolean isVisible() {
        return this.mShow;
    }

    /**
     * Setter for Color and Width properties.
     *
     * @param iColor iColor
     * @param fWidth fWidth
     */
    public void setStyle(int iColor, float fWidth) {
        mColor = iColor;
        mWidth = fWidth;
    }

    /**
     * Setter for Color, Width and UseDip properties.
     *
     * @param iColor iColor
     * @param fWidth fWidth
     * @param bUsedip bUsedip
     */
    public void setStyle(int iColor, float fWidth, boolean bUsedip) {
        mColor = iColor;
        mWidth = fWidth;
        mUseDip = bUsedip;
    }

    /**
     * Setter for Color, FillColor, Width and UseDip properties.
     *
     * @param iColor iColor
     * @param iFillColor iFillColor
     * @param fWidth fWidth
     * @param bUsedip bUsedip
     */
    public void setStyle(int iColor, int iFillColor, float fWidth, boolean bUsedip) {
        mColor = iColor;
        mFillColor = iFillColor;
        mWidth = fWidth;
        mUseDip = bUsedip;
    }
}
